package utils

import (
	"bufio"
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net"
	"net/http"
	"strings"
	"time"
)

type GenericRPCClient struct {
	URL      string
	Timeout  time.Duration
	Username string
	Password string
}

// Call 统一发起 JSON-RPC 调用，支持 HTTP 和 Unix socket 两种传输方式。

func (c *GenericRPCClient) Call(method string, params interface{}) (map[string]interface{}, error) {
	// Debug： 输出当前 URL
	fmt.Printf("DEBUG: Using URL: %s\n", c.URL)
	
	// 如果 URL 以 "unix:" 开头，则走 unix socket 逻辑，否则保证走 HTTP 分支
	if strings.HasPrefix(c.URL, "unix:") {
		// Unix socket 分支，保持不变
		address := strings.TrimPrefix(c.URL, "unix:")
		conn, err := net.DialTimeout("unix", address, c.Timeout)
		if err != nil {
			return nil, fmt.Errorf("dial unix socket error: %v", err)
		}
		defer conn.Close()
		conn.SetDeadline(time.Now().Add(c.Timeout))
		
		reqObj := map[string]interface{}{
			"jsonrpc": "2.0",
			"id":      1,
			"method":  method,
			"params":  params,
		}
		reqData, err := json.Marshal(reqObj)
		if err != nil {
			return nil, fmt.Errorf("marshal request error: %v", err)
		}
		_, err = conn.Write(append(reqData, '\n'))
		if err != nil {
			return nil, fmt.Errorf("write unix socket error: %v", err)
		}
		reader := bufio.NewReader(conn)
		line, err := reader.ReadBytes('\n')
		if err != nil {
			return nil, fmt.Errorf("read unix socket response error: %v", err)
		}
		var respObj map[string]interface{}
		if err := json.Unmarshal(line, &respObj); err != nil {
			return nil, fmt.Errorf("parse unix socket response error: %v", err)
		}
		return respObj, nil
	}
	
	// 走 HTTP 分支。确保 URL 有有效 Host，例如 "http://ip:port"
	if !strings.HasPrefix(c.URL, "http://") && !strings.HasPrefix(c.URL, "https://") {
		fmt.Printf("DEBUG: URL missing scheme, adding 'http://'\n")
		c.URL = "http://" + c.URL
	}

	reqObj := map[string]interface{}{
		"jsonrpc": "2.0",
		"id":      1,
		"method":  method,
		"params":  params,
	}
	reqData, err := json.Marshal(reqObj)
	if err != nil {
		return nil, fmt.Errorf("marshal request error: %v", err)
	}
	// Debug 输出请求内容
	fmt.Printf("DEBUG: GenericRPCClient Request: %s\n", reqData)
	
	req, err := http.NewRequest("POST", c.URL, bytes.NewReader(reqData))
	if err != nil {
		return nil, fmt.Errorf("create request error: %v", err)
	}
	if c.Username != "" || c.Password != "" {
		req.SetBasicAuth(c.Username, c.Password)
	}

	client := &http.Client{Timeout: c.Timeout}
	resp, err := client.Do(req)
	if err != nil {
		return nil, fmt.Errorf("http request error: %v", err)
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("read http response error: %v", err)
	}
	var respObj map[string]interface{}
	if err := json.Unmarshal(body, &respObj); err != nil {
		return nil, fmt.Errorf("parse http response error: %v", err)
	}
	// Debug 输出响应内容
	fmt.Printf("DEBUG: GenericRPCClient Raw Response: %s\n", body)
	return respObj, nil
}
